package controller

import (
	"crypto/rand"
	"encoding/json"
	"gdfs-center/controller/ao"
	"gdfs-center/controller/vo"
	"gdfs-center/db"
	"gdfs-center/engine"
	"gdfs-center/err"
	"gdfs-center/logcat"
	"gdfs-center/socket/cmdGenerate"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"math/big"
)

//全量同步
func SyncfullData(c *gin.Context) {
	c.Writer.Header().Set("content-type", "application/json")
	var syncdata ao.FullSyncData
	jsoner := json.Unmarshal(GetPostJson(c.Request), &syncdata)
	if jsoner != nil {
		WritedString(c.Writer, false, "-1", "json解析异常", nil)
		return
	}
	logcat.GetLog().Sugar().Infow("###全量同步接口-----------!", " //sid =", syncdata.StoreId, " //targetid=", syncdata.TargetId)
	//查找任务表
	var task db.SyncTask
	var store db.Store
	//查找源服务
	db.GetDB().Where("store_id = ?", syncdata.StoreId).First(&store)
	if store == (db.Store{}) {
		WritedString(c.Writer, false, err.FINDDBERR, err.Errortype[err.FINDDBERR], nil)
		return
	}
	task.StoreId = store.StoreId
	task.StoreIp = store.StoreIp
	//查找目标服务
	var target db.Store
	db.GetDB().Where("store_id = ?", syncdata.TargetId).First(&target)
	if target == (db.Store{}) {
		WritedString(c.Writer, false, err.FINDDBERR, err.Errortype[err.FINDDBERR], nil)
		return
	}
	task.TargetId = target.StoreId
	task.TargetIp = target.StoreIp
	task.Status = 0
	task.Percent = 0
	//查找所在NodeId
	var n db.Node
	db.GetDB().Where("node_id = ?", store.NodeId).First(&n)
	task.NodeId = store.NodeId
	task.NodeName = n.NodeName
	db.GetDB().Save(&task)
	WritedString(c.Writer, true, "0", "新建任务成功", nil)
	return
}

//分页获取任务记录
func GetSyncTaskPageList(c *gin.Context) {
	c.Writer.Header().Set("content-type", "application/json")
	var syncao ao.SyncFullData
	jsonerr := json.Unmarshal(GetPostJson(c.Request), &syncao)
	if jsonerr != nil {
		logcat.GetLog().Sugar().Info("###jsonerr:", jsonerr)
		WritedString(c.Writer, false, err.JSONERR, err.Errortype[err.JSONERR], nil)
		return
	}

	if syncao.PageNum == 0 {
		WritedString(c.Writer, false, err.NOTVALID_ERROR, err.Errortype[err.NOTVALID_ERROR], nil)
		return
	}
	if syncao.PageSize == 0 {
		WritedString(c.Writer, false, err.NOTVALID_ERROR, err.Errortype[err.NOTVALID_ERROR], nil)
		return
	}
	var pageresult vo.PageResult
	var scopes []func(*gorm.DB) *gorm.DB
	var total int64
	var tasks []db.SyncTask
	var tasksvo []vo.SyncTaskVo
	db.GetPageQueryTotal(scopes).Find(&tasks).Count(&total)
	db.PageQuery(scopes, syncao.PageSize, syncao.PageNum, "created_at desc").Find(&tasks)
	for _, task := range tasks {
		var vo vo.SyncTaskVo
		vo.StoreId = task.StoreId
		vo.StoreIp = task.StoreIp
		vo.TaskId = task.TaskId
		vo.Percent = task.Percent
		vo.TargetId = task.TargetId
		vo.TargetIp = task.TargetIp
		if task.Status == 0 {
			vo.Status = "stop"
		} else if task.Status == 1 {
			vo.Status = "running"
		} else if task.Status == 2 {
			vo.Status = "success"
		}
		vo.NodeName = task.NodeName
		vo.CreatedAt = task.CreatedAt.Format("2006-01-02 15:04:05")
		vo.UpdatedAt = task.UpdatedAt.Format("2006-01-02 15:04:05")
		tasksvo = append(tasksvo, vo)
	}
	pageresult.PageNum = syncao.PageNum
	pageresult.PageSize = syncao.PageSize
	pageresult.Pages = int(total) / syncao.PageSize
	pageresult.Total = total
	pageresult.List = tasksvo
	WritedString(c.Writer, true, "0", "处理成功", pageresult)
}

//停止全量任务
func StopSyncFullTask(c *gin.Context) {
	c.Writer.Header().Set("content-type", "application/json")
	var taskao ao.StartFullTaskAo
	jsonerr := json.Unmarshal(GetPostJson(c.Request), &taskao)
	if jsonerr != nil {
		logcat.GetLog().Sugar().Info("###jsonerr:", jsonerr)
		WritedString(c.Writer, false, err.JSONERR, err.Errortype[err.JSONERR], nil)
		return
	}
	//停止任务
	var task db.SyncTask
	db.GetDB().Where("task_id = ?", taskao.TaskId).First(&task)
	if task != (db.SyncTask{}) {
		if task.Status == 2 {
			WritedString(c.Writer, false, err.TASKFINISH, err.Errortype[err.TASKFINISH], nil)
			return
		}
		task.Status = 0
		db.GetDB().Save(&task)
		_, ok := engine.GetEngine().StoreMap[task.StoreId]
		_, ok2 := engine.GetEngine().StoreMap[task.TargetId]
		if ok && ok2 {
			s := engine.GetEngine().StoreMap[task.StoreId]
			t := engine.GetEngine().StoreMap[task.TargetId]
			if !s.Alive || !t.Alive {
				WritedString(c.Writer, false, err.DEVICEUNONLINE, err.Errortype[err.DEVICEUNONLINE], nil)
				return
			}
			s.Conn.Write(cmdGenerate.GenerateStopSyncDataCmd(task.TaskId))
			t.Conn.Write(cmdGenerate.GenerateStopSyncDataCmd(task.TaskId))
			WritedString(c.Writer, true, "0", "处理成功", nil)
			return
		}
	}
	WritedString(c.Writer, false, err.NODBERR, err.Errortype[err.NODBERR], nil)
}

//开始全量同步任务
func StartSyncFullDataTask(c *gin.Context) {
	c.Writer.Header().Set("content-type", "application/json")
	var taskao ao.StartFullTaskAo
	jsonerr := json.Unmarshal(GetPostJson(c.Request), &taskao)
	if jsonerr != nil {
		logcat.GetLog().Sugar().Info("###jsonerr:", jsonerr)
		WritedString(c.Writer, false, err.JSONERR, err.Errortype[err.JSONERR], nil)
		return
	}
	var task db.SyncTask
	db.GetDB().Where("task_id = ?", taskao.TaskId).First(&task)
	var tasks []db.SyncTask
	db.GetDB().Where("store_id = ?", task.StoreId, 1).Or("target_id = ?", task.TargetId).Find(&tasks)
	for _, t := range tasks {
		if t.Status == 1 || t.Status == 2 {
			//运行中
			WritedString(c.Writer, false, err.TASKRUNNING, err.Errortype[err.TASKRUNNING], nil)
			return
		}
	}
	task.Status = 1
	_, ok := engine.GetEngine().StoreMap[task.StoreId]
	_, ok2 := engine.GetEngine().StoreMap[task.TargetId]
	if ok && ok2 {
		src := engine.GetEngine().StoreMap[task.StoreId]
		target := engine.GetEngine().StoreMap[task.TargetId]
		//连接是正常的情况
		if !src.Alive || !target.Alive {
			WritedString(c.Writer, false, err.DEVICEUNONLINE, err.Errortype[err.DEVICEUNONLINE], nil)
			return
		}
		//发送给接收端
		dbport, _ := rand.Int(rand.Reader, big.NewInt(3300-1000))
		port := int(dbport.Int64() + 1000)
		task.DbPort = port
		db.GetDB().Save(&task)
		target.Conn.Write(cmdGenerate.GenerateTcpServer(task.TaskId, port))
		WritedString(c.Writer, true, "0", "处理成功", nil)
		return
	}
	WritedString(c.Writer, false, err.SENDERR, err.Errortype[err.SENDERR], nil)
}

//删除全量同步任务
func RemoveFullTask(c *gin.Context) {
	c.Writer.Header().Set("content-type", "application/json")
	var taskao ao.StartFullTaskAo
	jsonerr := json.Unmarshal(GetPostJson(c.Request), &taskao)
	if jsonerr != nil {
		logcat.GetLog().Sugar().Info("###jsonerr:", jsonerr)
		WritedString(c.Writer, false, err.JSONERR, err.Errortype[err.JSONERR], nil)
		return
	}
	var task db.SyncTask
	db.GetDB().Where("task_id = ?", taskao.TaskId).First(&task)
	if task != (db.SyncTask{}) {
		db.GetDB().Delete(&task)
		WritedString(c.Writer, true, "0", "处理成功", nil)
		return
	}
	WritedString(c.Writer, false, err.NODBERR, err.Errortype[err.NODBERR], nil)
}
